﻿using System.Collections.Generic;
using Windows.UI;
using LinkPad.Shapes;
using Windows.UI.Xaml.Input;

namespace LinkPad.Handlers
{
    class Editor : CanvasActionHandler, IHasFont
    {
        #region Fields

        private readonly List<ICanvasActionPublicHandler> _subEditors = new List<ICanvasActionPublicHandler>();

        private ICanvasActionPublicHandler _tappedObjectHandler;

        private bool _multi;

        #endregion

        #region Constructors

        public Editor(ShapeManager shapeManager, IGlobalController globalController)
            : base(shapeManager)
        {
            GlobalController = globalController;
        }

        #endregion

        #region Properties

        #region CanvasActionHandler members

        public override bool HasColor
        {
            get
            {
                var objHasColor = _tappedObjectHandler as IHasColor;
                return objHasColor != null && objHasColor.HasColor;
            }
        }

        public override Color MainColor
        {
            get
            {
                var objHasColor = _tappedObjectHandler as IHasColor;
                if (objHasColor == null)
                {
                    return base.MainColor;
                }
                return objHasColor.MainColor;
            }
            set
            {
                var objHasColor = _tappedObjectHandler as IHasColor;
                if (objHasColor != null)
                {
                    objHasColor.MainColor = value;
                }
                else
                {
                    base.MainColor = value;
                }
            }
        }

        #endregion

        #region IHasFont members

        public bool HasFont 
        {
            get
            {
                var objHasColor = _tappedObjectHandler as IHasFont;
                return objHasColor != null && objHasColor.HasFont;
            }
        }

        public double FontSize
        {
            get
            {
                var objHasColor = _tappedObjectHandler as IHasFont;
                if (objHasColor == null)
                {
                    return 0;
                }
                return objHasColor.FontSize;
            }
            set
            {
                var objHasColor = _tappedObjectHandler as IHasFont;
                if (objHasColor != null)
                {
                    objHasColor.FontSize = value;
                }
            }
        }

        #endregion

        public IReadOnlyList<ICanvasActionPublicHandler> SubEditors
        {
            get
            {
                return _subEditors;
            }
        }

        public IGlobalController GlobalController { get; private set; }


        #endregion

        #region Methods

        #region CanvasActionHandler members

        public override void Deactivate()
        {
            if (_tappedObjectHandler != null)
            {
                _tappedObjectHandler.HandleDeactivated();
            }
            base.Deactivate();
        }

        protected override void HandleCanvasDoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
        {
            foreach (var subeditor in SubEditors)
            {
                subeditor.HandleCanvasDoubleTapped(sender, e);
                if (e.Handled)
                {
                    _tappedObjectHandler = subeditor;
                    break;
                }
            }
            base.HandleCanvasDoubleTapped(sender, e);
        }

        protected override void HandleCanvasTapped(object sender, TappedRoutedEventArgs e)
        {
            foreach (var subeditor in SubEditors)
            {
                subeditor.HandleCanvasTapped(sender, e);
                if (e.Handled)
                {
                    _tappedObjectHandler = subeditor;
                    break;
                }
            }
            base.HandleCanvasTapped(sender, e);
        }

        protected override void HandlePointerPressed(object sender, PointerRoutedEventArgs e)
        {
            var wasMulti = _multi;
            _multi = false;
            ICanvasActionPublicHandler clearOthers = null;
            foreach (var subeditor in SubEditors)
            {
                subeditor.HandlePointerPressed(sender, e);
                if (subeditor.MultiSelectStatus == MultiSelectStatus.Multi)
                {
                    _multi = true;
                }
                else if (subeditor.MultiSelectStatus == MultiSelectStatus.NonMultiResetAll)
                {
                    clearOthers = subeditor;
                    _multi = false;
                    e.Handled = true;
                }
                if (!(wasMulti || _multi) && e.Handled)
                {
                    _tappedObjectHandler = subeditor;
                    break;
                }
            }

            foreach (var subeditor in SubEditors)
            {
                var isToEmpty = subeditor.MultiSelectStatus == MultiSelectStatus.Empty && !_multi;
                subeditor.MultiSelectStatus = _multi ? MultiSelectStatus.Multi : MultiSelectStatus.NonMulti;
                if (!_multi && clearOthers != null && clearOthers != subeditor || isToEmpty)
                {
                    subeditor.DeselectAll();
                    subeditor.MultiSelectStatus= MultiSelectStatus.NonMulti;
                }
            }

            base.HandlePointerPressed(sender, e);
        }

        protected override void HandlePointerMoved(object sender, PointerRoutedEventArgs e)
        {
            foreach (var subeditor in SubEditors)
            {
                subeditor.HandlePointerMoved(sender, e);
                if (!_multi && e.Handled)
                {
                    break;
                }
            }
            base.HandlePointerMoved(sender, e);
        }

        protected override void HandlePointerReleased(object sender, PointerRoutedEventArgs e)
        {
            foreach (var subeditor in SubEditors)
            {
                subeditor.HandlePointerReleased(sender, e);
                if (!_multi && e.Handled)
                {
                    break;
                }
            }
            base.HandlePointerReleased(sender, e);
        }

        protected override void HandlePointerExited(object sender, PointerRoutedEventArgs e)
        {
            foreach (var subeditor in SubEditors)
            {
                subeditor.HandlePointerExited(sender, e);
                if (!_multi && e.Handled)
                {
                    break;
                }
            }
            base.HandlePointerExited(sender, e);
        }

        #endregion

        public void DeleteAllSelected()
        {
            foreach (var subeditor in SubEditors)
            {
                subeditor.DeleteAllSelected();
            }
        }

        public void AddSubEditor(ICanvasActionPublicHandler subEditor)
        {
            _subEditors.Add(subEditor);
            var ss = subEditor as ISubEditor;
            if (ss != null)
            {
                ss.Parent = this;
            }
        }

        public bool HasOtherSelected(ISubEditor current)
        {
            foreach (var s in _subEditors)
            {
                if (s == current) continue;
                var subEditor = s as ISubEditor;
                if (subEditor == null) continue;
                if (subEditor.HasSelected)
                {
                    return true;
                }
            }
            return false;
        }

        #endregion
    }
}
